/*
	This file is part of Floculate.
	Copyright (C) 2008  Bill Whitacre

	Floculate is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	Floculate is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef KEYMAP_H
#define KEYMAP_H

#if defined(__linux__)
#	include <X11/X.h>
#	include <X11/keysym.h>
#elif defined(WIN32)||defined(_WIN32)||defined(__WIN32)||\
	defined(__WIN32__)||defined(Win32)
#	include <windows.h>
#endif

#include <stdlib.h>
#include <string.h>

typedef unsigned int RAT_KEY_CODE;

#define RAT_KEY_LBUTTON            0x01   // Left mouse button
#define RAT_KEY_RBUTTON            0x02   // Right mouse button
#define RAT_KEY_CANCEL             0x03   // Control-break processing
#define RAT_KEY_MBUTTON            0x04   // Middle mouse button (three-button mouse)
#define RAT_KEY_XBUTTON1           0x05   // Windows 2000/XP: X1 mouse button
#define RAT_KEY_XBUTTON2           0x06   // Windows 2000/XP: X2 mouse button
#define RAT_KEY_BACK               0x08   // BACKSPACE key
#define RAT_KEY_TAB                0x09   // TAB key
#define RAT_KEY_CLEAR              0x0C   // CLEAR key
#define RAT_KEY_RETURN             0x0D   // ENTER key
#define RAT_KEY_SHIFT              0x10   // SHIFT key
#define RAT_KEY_CONTROL            0x11   // CTRL key
#define RAT_KEY_MENU               0x12   // ALT key
#define RAT_KEY_PAUSE              0x13   // PAUSE key
#define RAT_KEY_CAPITAL            0x14   // CAPS LOCK key
#define RAT_KEY_KANA               0x15   // IME Kana mode
#define RAT_KEY_HANGUEL            0x15   // IME Hanguel mode (maintained for compatibility use RAT_KEY_HANGUL)
#define RAT_KEY_HANGUL             0x15   // IME Hangul mode
#define RAT_KEY_JUNJA              0x17   // IME Junja mode
#define RAT_KEY_FINAL              0x18   // IME final mode
#define RAT_KEY_HANJA              0x19   // IME Hanja mode
#define RAT_KEY_KANJI              0x19   // IME Kanji mode
#define RAT_KEY_ESCAPE             0x1B   // ESC key
#define RAT_KEY_CONVERT            0x1C   // IME convert
#define RAT_KEY_NONCONVERT         0x1D   // IME nonconvert
#define RAT_KEY_ACCEPT             0x1E   // IME accept
#define RAT_KEY_MODECHANGE         0x1F   // IME mode change request
#define RAT_KEY_SPACE              0x20   // SPACEBAR
#define RAT_KEY_PRIOR              0x21   // PAGE UP key
#define RAT_KEY_NEXT               0x22   // PAGE DOWN key
#define RAT_KEY_END                0x23   // END key
#define RAT_KEY_HOME               0x24   // HOME key
#define RAT_KEY_LEFT               0x25   // LEFT ARROW key
#define RAT_KEY_UP                 0x26   // UP ARROW key
#define RAT_KEY_RIGHT              0x27   // RIGHT ARROW key
#define RAT_KEY_DOWN               0x28   // DOWN ARROW key
#define RAT_KEY_SELECT             0x29   // SELECT key
#define RAT_KEY_PRINT              0x2A   // PRINT key
#define RAT_KEY_EXECUT             0x2B   // EXECUTE key
#define RAT_KEY_SNAPSHOT           0x2C   // PRINT SCREEN key
#define RAT_KEY_INSERT             0x2D   // INS key
#define RAT_KEY_DELETE             0x2E   // DEL key
#define RAT_KEY_HELP               0x2F   // HELP key
#define RAT_KEY_KEY_0           0x30   // 0 key
#define RAT_KEY_KEY_1           0x31   // 1 key
#define RAT_KEY_KEY_2           0x32   // 2 key
#define RAT_KEY_KEY_3           0x33   // 3 key
#define RAT_KEY_KEY_4           0x34   // 4 key
#define RAT_KEY_KEY_5           0x35   // 5 key
#define RAT_KEY_KEY_6           0x36   // 6 key
#define RAT_KEY_KEY_7           0x37   // 7 key
#define RAT_KEY_KEY_8           0x38   // 8 key
#define RAT_KEY_KEY_9           0x39   // 9 key
#define RAT_KEY_KEY_A           0x41   // A key
#define RAT_KEY_KEY_B           0x42   // B key
#define RAT_KEY_KEY_C           0x43   // C key
#define RAT_KEY_KEY_D           0x44   // D key
#define RAT_KEY_KEY_E           0x45   // E key
#define RAT_KEY_KEY_F           0x46   // F key
#define RAT_KEY_KEY_G           0x47   // G key
#define RAT_KEY_KEY_H           0x48   // H key
#define RAT_KEY_KEY_I           0x49   // I key
#define RAT_KEY_KEY_J           0x4A   // J key
#define RAT_KEY_KEY_K           0x4B   // K key
#define RAT_KEY_KEY_L           0x4C   // L key
#define RAT_KEY_KEY_M           0x4D   // M key
#define RAT_KEY_KEY_N           0x4E   // N key
#define RAT_KEY_KEY_O           0x4F   // O key
#define RAT_KEY_KEY_P           0x50   // P key
#define RAT_KEY_KEY_Q           0x51   // Q key
#define RAT_KEY_KEY_R           0x52   // R key
#define RAT_KEY_KEY_S           0x53   // S key
#define RAT_KEY_KEY_T           0x54   // T key
#define RAT_KEY_KEY_U           0x55   // U key
#define RAT_KEY_KEY_V           0x56   // V key
#define RAT_KEY_KEY_W           0x57   // W key
#define RAT_KEY_KEY_X           0x58   // X key
#define RAT_KEY_KEY_Y           0x59   // Y key
#define RAT_KEY_KEY_Z          	0x5A   // Z key
#define RAT_KEY_LSUPER             0x5B   // Left Super (sometimes windows) key (Natural keyboard)
#define RAT_KEY_RSUPER             0x5C   // Left Super (sometimes windows) key (Natural keyboard)
#define RAT_KEY_APPS               0x5D   // Applications key (Natural keyboard)
#define RAT_KEY_SLEEP              0x5F   // Computer Sleep key
#define RAT_KEY_NUMPAD0            0x60   // Numeric keypad 0 key
#define RAT_KEY_NUMPAD1            0x61   // Numeric keypad 1 key
#define RAT_KEY_NUMPAD2            0x62   // Numeric keypad 2 key
#define RAT_KEY_NUMPAD3            0x63   // Numeric keypad 3 key
#define RAT_KEY_NUMPAD4            0x64   // Numeric keypad 4 key
#define RAT_KEY_NUMPAD5            0x65   // Numeric keypad 5 key
#define RAT_KEY_NUMPAD6            0x66   // Numeric keypad 6 key
#define RAT_KEY_NUMPAD7            0x67   // Numeric keypad 7 key
#define RAT_KEY_NUMPAD8            0x68   // Numeric keypad 8 key
#define RAT_KEY_NUMPAD9            0x69   // Numeric keypad 9 key
#define RAT_KEY_MULTIPLY           0x6A   // Multiply key
#define RAT_KEY_ADD                0x6B   // Add key
#define RAT_KEY_SEPARATOR          0x6C   // Separator key
#define RAT_KEY_SUBTRACT           0x6D   // Subtract key
#define RAT_KEY_DECIMAL            0x6E   // Decimal key
#define RAT_KEY_DIVIDE             0x6F   // Divide key
#define RAT_KEY_F1                 0x70   // F1 key
#define RAT_KEY_F2                 0x71   // F2 key
#define RAT_KEY_F3                 0x72   // F3 key
#define RAT_KEY_F4                 0x73   // F4 key
#define RAT_KEY_F5                 0x74   // F5 key
#define RAT_KEY_F6                 0x75   // F6 key
#define RAT_KEY_F7                 0x76   // F7 key
#define RAT_KEY_F8                 0x77   // F8 key
#define RAT_KEY_F9                 0x78   // F9 key
#define RAT_KEY_F10                0x79   // F10 key
#define RAT_KEY_F11                0x7A   // F11 key
#define RAT_KEY_F12                0x7B   // F12 key
#define RAT_KEY_F13                0x7C   // F13 key
#define RAT_KEY_F14                0x7D   // F14 key
#define RAT_KEY_F15                0x7E   // F15 key
#define RAT_KEY_F16                0x7F   // F16 key
#define RAT_KEY_F17                0x80   // F17 key
#define RAT_KEY_F18                0x81   // F18 key
#define RAT_KEY_F19                0x82   // F19 key
#define RAT_KEY_F20                0x83   // F20 key
#define RAT_KEY_F21                0x84   // F21 key
#define RAT_KEY_F22                0x85   // F22 key
#define RAT_KEY_F23                0x86   // F23 key
#define RAT_KEY_F24                0x87   // F24 key
#define RAT_KEY_NUMLOCK            0x90   // NUM LOCK key
#define RAT_KEY_SCROLL             0x91   // SCROLL LOCK key
#define RAT_KEY_LSHIFT             0xA0   // Left SHIFT key
#define RAT_KEY_RSHIFT             0xA1   // Right SHIFT key
#define RAT_KEY_LCONTROL           0xA2   // Left CONTROL key
#define RAT_KEY_RCONTROL           0xA3   // Right CONTROL key
#define RAT_KEY_LMENU              0xA4   // Left MENU key
#define RAT_KEY_RMENU              0xA5   // Right MENU key
#define RAT_KEY_PLUS               0xBB   // Plus Key   (+)
#define RAT_KEY_COMMA              0xBC   // Comma Key  (,)
#define RAT_KEY_MINUS              0xBD   // Minus Key  (-)
#define RAT_KEY_PERIOD             0xBE   // Period Key (.)
#define RAT_KEY_ATTN               0xF6   // Attn key
#define RAT_KEY_CRSEL              0xF7   // CrSel key
#define RAT_KEY_EXSEL              0xF8   // ExSel key
#define RAT_KEY_EREOF              0xF9   // Erase EOF key
#define RAT_KEY_PLAY               0xFA   // Play key
#define RAT_KEY_ZOOM               0xFB   // Zoom key
#define RAT_KEY_PA1                0xFD   // PA1 key
#define RAT_KEY_OEM_CLEAR          0xFE   // Clear key
#define RAT_KEY_CODE_COUNT         0xFF   // number of keycodes (255. beautiful.)

#if defined(__linux__)
    typedef KeySym RAT_SYS_KEY;
#elif defined(WIN32)||defined(_WIN32)||defined(__WIN32)||\
	defined(__WIN32__)||defined(Win32)
    typedef long RAT_SYS_KEY;
#endif

typedef struct rat_key_pair
{
    RAT_KEY_CODE rekey;
    RAT_SYS_KEY syskey;
} rat_key_pair;

typedef struct rat_key_map
{
    int numpairs;
    rat_key_pair *keypairs;
} rat_key_map;

rat_key_pair rat_key_pair_create(RAT_SYS_KEY syskey,RAT_KEY_CODE rekey);

rat_key_map *rat_key_map_create();
void rat_key_map_destroy(rat_key_map *keymap);

void rat_key_map_add_pair(rat_key_map *keymap,rat_key_pair keypair);
RAT_KEY_CODE rat_key_map_get_code(rat_key_map *keymap,RAT_SYS_KEY syskey);

void rat_key_map_sort(rat_key_map *keymap);

#endif
